﻿using Microsoft.Web.WebView2.Wpf;
using Prism.Commands;
using Prism.Mvvm;
using RSDesktop.Views.Popup;
using RSFrame.Services;
using RSModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;

namespace RSDesktop.ViewModels
{
    public class WorkWindowViewModel : BindableBase
    {
        public Workspace CurrentWorkspace { get; set; }

        public ICompanyService CompanyService { get; set; }

        public ICarService CarService { get; set; }

        private List<Company> searchResult;
        /// <summary>
        /// 搜索结果
        /// </summary>
        public List<Company> SearchResult
        {
            get { return searchResult; }
            set
            {
                SetProperty(ref searchResult, value);
                if (value == null)
                    SearchResultCount = 0;
                else
                    SearchResultCount = value.Count;
            }
        }

        private int searchResultCount;
        /// <summary>
        /// 搜索结果数量
        /// </summary>
        public int SearchResultCount
        {
            get { return searchResultCount; }
            set { SetProperty(ref searchResultCount, value); }
        }

        private List<Car> searchCarResult;

        public List<Car> SearchCarResult
        {
            get { return searchCarResult; }
            set { SetProperty(ref searchCarResult, value); }
        }

        public DelegateCommand<string> SearchCommand { get; set; }

        public DelegateCommand<string> SearchCarCommand { get; set; }

        public DelegateCommand<object> AddCommand { get; set; }

        public DelegateCommand<object> DeleteCommand { get; set; }

        public DelegateCommand<object> PosCommand { get; set; }

        public DelegateCommand<object> AssetsCommand { get; set; }

        public WorkWindowViewModel(Workspace currentWorkspace, ICompanyService companyService, ICarService carService)
        {
            CurrentWorkspace = currentWorkspace;
            CompanyService = companyService;
            CarService = carService;
            SearchCommand = new DelegateCommand<string>(ExecSearch);
            AddCommand = new DelegateCommand<object>(ExecAdd);
            DeleteCommand = new DelegateCommand<object>(ExecDelete);
            PosCommand = new DelegateCommand<object>(ExecPos);
            SearchCarCommand = new DelegateCommand<string>(ExecSearchCar);
            AssetsCommand = new DelegateCommand<object>(ExecAssets);
        }

        private async void ExecSearch(string keyword)
        {
            if (!string.IsNullOrWhiteSpace(keyword))
                SearchResult = await SearchAsync(keyword.Trim());
        }

        private Task<List<Company>> SearchAsync(string keyword)
        {
            var result = new TaskCompletionSource<List<Company>>();
            new Thread(() =>
            {
                if (keyword == "*")
                    result.SetResult(CompanyService.AllAuthorizedCompanies);
                else if (int.TryParse(keyword, out int temp))
                    result.SetResult(CompanyService.SearchCompanyByID(temp));
                else
                    result.SetResult(CompanyService.SearchCompanyByName(keyword));
            })
            { IsBackground = true }.Start();
            return result.Task;
        }

        private async void ExecAdd(object parameters)
        {
            object[] a = parameters as object[];
            string name = (string)a[0];
            string des = (string)a[1];
            int type = (int)a[2];
            string[] pos = ((string)a[3]).Split(',');
            if (name != string.Empty && des != string.Empty && type != -1 && float.TryParse(pos[0], out float _lng) && float.TryParse(pos[1], out float _lat))
            {
                int? r = await AddAsync(name, des, type, _lng, _lat);
                if (r == null)
                    new TipWindow("警告", "添加失败。请检查网络连接或用户权限").Show();
                else
                {
                    new TipWindow("提示", $"添加成功，公司ID为{r}").Show();
                    SearchResult = await SearchAsync("*");
                }
            }
            else
                new TipWindow("警告", "参数格式错误，请检查填写内容。每项均为必填项，公司位置信息请在下方地图单击以获得坐标。").Show();
        }

        private Task<int?> AddAsync(string name, string des, int type, float lng, float lat)
        {
            var result = new TaskCompletionSource<int?>();
            new Thread(() =>
            {
                result.SetResult(CompanyService.AddCompany(name, des, type, lng, lat, CurrentWorkspace.CurrentUser.Account, CurrentWorkspace.CurrentUser.Password));
            })
            { IsBackground = true }.Start();
            return result.Task;
        }

        private async void ExecDelete(object o)
        {
            if (o is Company a)
            {
                bool result = await DeleteAsync(a.ID);
                if (result)
                {
                    new TipWindow("提示", "删除成功！").Show();
                    SearchResult = await SearchAsync("*");
                }
                else
                    new TipWindow("错误", "删除失败。请检查网络连接或用户权限").Show();
            }
            else
                new TipWindow("提示", "请先在左侧选择一个要取消认证的公司").Show();
        }

        private Task<bool> DeleteAsync(int id)
        {
            var result = new TaskCompletionSource<bool>();
            new Thread(() =>
            {
                result.SetResult(CompanyService.DeleteCompany(id, CurrentWorkspace.CurrentUser.Account, CurrentWorkspace.CurrentUser.Password));
            })
            { IsBackground = true }.Start();
            return result.Task;
        }

        private async void ExecPos(object o)
        {
            object[] temp = o as object[];
            if (temp[0] is WebView2 map && temp[1] is Company company)
                await map.ExecuteScriptAsync($"setMarker({company.CompanyPosition.Lng},{company.CompanyPosition.Lat})");
            else
                new TipWindow("提示", "请先在左侧选择一个要定位的公司").Show();
        }

        private async void ExecSearchCar(string keyword)
        {
            if (!string.IsNullOrWhiteSpace(keyword))
                SearchCarResult = await SearchCarAsync(keyword.Trim());
        }

        private Task<List<Car>> SearchCarAsync(string keyword)
        {
            var result = new TaskCompletionSource<List<Car>>();
            new Thread(() =>
            {
                if (keyword == "*")
                    result.SetResult(CarService.AllCars);
                else if (int.TryParse(keyword, out int temp))
                    result.SetResult(new List<Car>() { CarService.GetCarByID(temp) });
                else
                    result.SetResult(new List<Car>());
            })
            { IsBackground = true }.Start();
            return result.Task;
        }

        private void ExecAssets(object o)
        {
            if (o is Company c)
                new AssetsInfo(c).Show();
            else
                new TipWindow("提示", "请先选择要查看的公司").Show();
        }
    }
}
